/*
 * LvStyle.h
 *
 */

#ifndef LVSTYLE_H_
#define LVSTYLE_H_

#include "../core/lvglpp.h"

namespace lvglpp
{

	class LvStyle : protected lv_style_t
	{
		inline auto &_self() noexcept { return *this; }

	public:
		/**
		 * Initialize a style
		 * @param style pointer to a style to initialize
		 * @note Do not call `lv_style_init` on styles that already have some properties
		 *       because this function won't free the used memory, just sets a default state for the style.
		 *       In other words be sure to initialize styles only once!
		 */
		LvStyle() noexcept { lv_style_init(this); }

		~LvStyle() noexcept { reset(); }

		lv_style_t *raw() noexcept { return this; }
		const lv_style_t *raw() const noexcept { return this; }

		using TSelf = LvStyle;

		/**
		 * Initialize a transition descriptor.
		 * @param tr        pointer to a transition descriptor to initialize
		 * @param props     an array with the properties to transition. The last element must be zero.
		 * @param path_cb   an animation path (ease) callback. If `NULL` liner path will be used.
		 * @param time      duration of the transition in [ms]
		 * @param delay     delay before the transition in [ms]
		 * @param user_data any custom data that will be saved in the transition animation and will be available when `path_cb` is called
		 * @example
		 * const static lv_style_prop_t trans_props[] = { LV_STYLE_BG_OPA, LV_STYLE_BG_COLOR, 0 };
		 *  static lv_style_transition_dsc_t trans1;
		 *  lv_style_transition_dsc_init(&trans1, trans_props, NULL, 300, 0, NULL);
		 */
		static void transitionDscInit(lv_style_transition_dsc_t *tr, const lv_style_prop_t props[], lv_anim_path_cb_t path_cb, uint32_t time, uint32_t delay, void *user_data) noexcept { return lv_style_transition_dsc_init(tr, props, path_cb, time, delay, user_data); }

		/**
		 * Tell the group of a property. If the a property from a group is set in a style the (1 << group) bit of style->has_group is set.
		 * It allows early skipping the style if the property is not exists in the style at all.
		 * @param prop a style property
		 * @return the group [0..7] 7 means all the custom properties with index > 112
		 */
		static uint8_t getPropGroup(lv_style_prop_t prop) noexcept { return _lv_style_get_prop_group(prop); }

	public:
		//+gen
		inline TSelf &init() { return lv_style_init(raw()), _self(); }
		inline TSelf &reset() { return lv_style_reset(raw()), _self(); }
		static inline lv_style_prop_t registerProp() { return lv_style_register_prop(); }
		inline bool removeProp(lv_style_prop_t prop) { return lv_style_remove_prop(raw(), prop); }
		inline TSelf &setProp(lv_style_prop_t prop, lv_style_value_t value) { return lv_style_set_prop(raw(), prop, value), _self(); }
		inline lv_res_t getProp(lv_style_prop_t prop, lv_style_value_t *value) const { return lv_style_get_prop(raw(), prop, value); }
		inline lv_res_t getPropInlined(lv_style_prop_t prop, lv_style_value_t *value) const { return lv_style_get_prop_inlined(raw(), prop, value); }
		static inline lv_style_value_t propGetDefault(lv_style_prop_t prop) { return lv_style_prop_get_default(prop); }
		inline bool isEmpty() const { return lv_style_is_empty(raw()); }
		inline TSelf &setWidth(lv_coord_t value) { return lv_style_set_width(raw(), value), _self(); }
		inline TSelf &setMinWidth(lv_coord_t value) { return lv_style_set_min_width(raw(), value), _self(); }
		inline TSelf &setMaxWidth(lv_coord_t value) { return lv_style_set_max_width(raw(), value), _self(); }
		inline TSelf &setHeight(lv_coord_t value) { return lv_style_set_height(raw(), value), _self(); }
		inline TSelf &setMinHeight(lv_coord_t value) { return lv_style_set_min_height(raw(), value), _self(); }
		inline TSelf &setMaxHeight(lv_coord_t value) { return lv_style_set_max_height(raw(), value), _self(); }
		inline TSelf &setX(lv_coord_t value) { return lv_style_set_x(raw(), value), _self(); }
		inline TSelf &setY(lv_coord_t value) { return lv_style_set_y(raw(), value), _self(); }
		inline TSelf &setAlign(lv_align_t value) { return lv_style_set_align(raw(), value), _self(); }
		inline TSelf &setTransformWidth(lv_coord_t value) { return lv_style_set_transform_width(raw(), value), _self(); }
		inline TSelf &setTransformHeight(lv_coord_t value) { return lv_style_set_transform_height(raw(), value), _self(); }
		inline TSelf &setTranslateX(lv_coord_t value) { return lv_style_set_translate_x(raw(), value), _self(); }
		inline TSelf &setTranslateY(lv_coord_t value) { return lv_style_set_translate_y(raw(), value), _self(); }
		inline TSelf &setTransformZoom(lv_coord_t value) { return lv_style_set_transform_zoom(raw(), value), _self(); }
		inline TSelf &setTransformAngle(lv_coord_t value) { return lv_style_set_transform_angle(raw(), value), _self(); }
		inline TSelf &setPadTop(lv_coord_t value) { return lv_style_set_pad_top(raw(), value), _self(); }
		inline TSelf &setPadBottom(lv_coord_t value) { return lv_style_set_pad_bottom(raw(), value), _self(); }
		inline TSelf &setPadLeft(lv_coord_t value) { return lv_style_set_pad_left(raw(), value), _self(); }
		inline TSelf &setPadRight(lv_coord_t value) { return lv_style_set_pad_right(raw(), value), _self(); }
		inline TSelf &setPadRow(lv_coord_t value) { return lv_style_set_pad_row(raw(), value), _self(); }
		inline TSelf &setPadColumn(lv_coord_t value) { return lv_style_set_pad_column(raw(), value), _self(); }
		inline TSelf &setBgColor(lv_color_t value) { return lv_style_set_bg_color(raw(), value), _self(); }
		inline TSelf &setBgColorFiltered(lv_color_t value) { return lv_style_set_bg_color_filtered(raw(), value), _self(); }
		inline TSelf &setBgOpa(lv_opa_t value) { return lv_style_set_bg_opa(raw(), value), _self(); }
		inline TSelf &setBgGradColor(lv_color_t value) { return lv_style_set_bg_grad_color(raw(), value), _self(); }
		inline TSelf &setBgGradColorFiltered(lv_color_t value) { return lv_style_set_bg_grad_color_filtered(raw(), value), _self(); }
		inline TSelf &setBgGradDir(lv_grad_dir_t value) { return lv_style_set_bg_grad_dir(raw(), value), _self(); }
		inline TSelf &setBgMainStop(lv_coord_t value) { return lv_style_set_bg_main_stop(raw(), value), _self(); }
		inline TSelf &setBgGradStop(lv_coord_t value) { return lv_style_set_bg_grad_stop(raw(), value), _self(); }
		inline TSelf &setBgGrad(const lv_grad_dsc_t *value) { return lv_style_set_bg_grad(raw(), value), _self(); }
		inline TSelf &setBgDitherMode(lv_dither_mode_t value) { return lv_style_set_bg_dither_mode(raw(), value), _self(); }
		inline TSelf &setBgImgSrc(const void *value) { return lv_style_set_bg_img_src(raw(), value), _self(); }
		inline TSelf &setBgImgOpa(lv_opa_t value) { return lv_style_set_bg_img_opa(raw(), value), _self(); }
		inline TSelf &setBgImgRecolor(lv_color_t value) { return lv_style_set_bg_img_recolor(raw(), value), _self(); }
		inline TSelf &setBgImgRecolorFiltered(lv_color_t value) { return lv_style_set_bg_img_recolor_filtered(raw(), value), _self(); }
		inline TSelf &setBgImgRecolorOpa(lv_opa_t value) { return lv_style_set_bg_img_recolor_opa(raw(), value), _self(); }
		inline TSelf &setBgImgTiled(bool value) { return lv_style_set_bg_img_tiled(raw(), value), _self(); }
		inline TSelf &setBorderColor(lv_color_t value) { return lv_style_set_border_color(raw(), value), _self(); }
		inline TSelf &setBorderColorFiltered(lv_color_t value) { return lv_style_set_border_color_filtered(raw(), value), _self(); }
		inline TSelf &setBorderOpa(lv_opa_t value) { return lv_style_set_border_opa(raw(), value), _self(); }
		inline TSelf &setBorderWidth(lv_coord_t value) { return lv_style_set_border_width(raw(), value), _self(); }
		inline TSelf &setBorderSide(lv_border_side_t value) { return lv_style_set_border_side(raw(), value), _self(); }
		inline TSelf &setBorderPost(bool value) { return lv_style_set_border_post(raw(), value), _self(); }
		inline TSelf &setOutlineWidth(lv_coord_t value) { return lv_style_set_outline_width(raw(), value), _self(); }
		inline TSelf &setOutlineColor(lv_color_t value) { return lv_style_set_outline_color(raw(), value), _self(); }
		inline TSelf &setOutlineColorFiltered(lv_color_t value) { return lv_style_set_outline_color_filtered(raw(), value), _self(); }
		inline TSelf &setOutlineOpa(lv_opa_t value) { return lv_style_set_outline_opa(raw(), value), _self(); }
		inline TSelf &setOutlinePad(lv_coord_t value) { return lv_style_set_outline_pad(raw(), value), _self(); }
		inline TSelf &setShadowWidth(lv_coord_t value) { return lv_style_set_shadow_width(raw(), value), _self(); }
		inline TSelf &setShadowOfsX(lv_coord_t value) { return lv_style_set_shadow_ofs_x(raw(), value), _self(); }
		inline TSelf &setShadowOfsY(lv_coord_t value) { return lv_style_set_shadow_ofs_y(raw(), value), _self(); }
		inline TSelf &setShadowSpread(lv_coord_t value) { return lv_style_set_shadow_spread(raw(), value), _self(); }
		inline TSelf &setShadowColor(lv_color_t value) { return lv_style_set_shadow_color(raw(), value), _self(); }
		inline TSelf &setShadowColorFiltered(lv_color_t value) { return lv_style_set_shadow_color_filtered(raw(), value), _self(); }
		inline TSelf &setShadowOpa(lv_opa_t value) { return lv_style_set_shadow_opa(raw(), value), _self(); }
		inline TSelf &setImgOpa(lv_opa_t value) { return lv_style_set_img_opa(raw(), value), _self(); }
		inline TSelf &setImgRecolor(lv_color_t value) { return lv_style_set_img_recolor(raw(), value), _self(); }
		inline TSelf &setImgRecolorFiltered(lv_color_t value) { return lv_style_set_img_recolor_filtered(raw(), value), _self(); }
		inline TSelf &setImgRecolorOpa(lv_opa_t value) { return lv_style_set_img_recolor_opa(raw(), value), _self(); }
		inline TSelf &setLineWidth(lv_coord_t value) { return lv_style_set_line_width(raw(), value), _self(); }
		inline TSelf &setLineDashWidth(lv_coord_t value) { return lv_style_set_line_dash_width(raw(), value), _self(); }
		inline TSelf &setLineDashGap(lv_coord_t value) { return lv_style_set_line_dash_gap(raw(), value), _self(); }
		inline TSelf &setLineRounded(bool value) { return lv_style_set_line_rounded(raw(), value), _self(); }
		inline TSelf &setLineColor(lv_color_t value) { return lv_style_set_line_color(raw(), value), _self(); }
		inline TSelf &setLineColorFiltered(lv_color_t value) { return lv_style_set_line_color_filtered(raw(), value), _self(); }
		inline TSelf &setLineOpa(lv_opa_t value) { return lv_style_set_line_opa(raw(), value), _self(); }
		inline TSelf &setArcWidth(lv_coord_t value) { return lv_style_set_arc_width(raw(), value), _self(); }
		inline TSelf &setArcRounded(bool value) { return lv_style_set_arc_rounded(raw(), value), _self(); }
		inline TSelf &setArcColor(lv_color_t value) { return lv_style_set_arc_color(raw(), value), _self(); }
		inline TSelf &setArcColorFiltered(lv_color_t value) { return lv_style_set_arc_color_filtered(raw(), value), _self(); }
		inline TSelf &setArcOpa(lv_opa_t value) { return lv_style_set_arc_opa(raw(), value), _self(); }
		inline TSelf &setArcImgSrc(const void *value) { return lv_style_set_arc_img_src(raw(), value), _self(); }
		inline TSelf &setTextColor(lv_color_t value) { return lv_style_set_text_color(raw(), value), _self(); }
		inline TSelf &setTextColorFiltered(lv_color_t value) { return lv_style_set_text_color_filtered(raw(), value), _self(); }
		inline TSelf &setTextOpa(lv_opa_t value) { return lv_style_set_text_opa(raw(), value), _self(); }
		inline TSelf &setTextFont(const lv_font_t *value) { return lv_style_set_text_font(raw(), value), _self(); }
		inline TSelf &setTextLetterSpace(lv_coord_t value) { return lv_style_set_text_letter_space(raw(), value), _self(); }
		inline TSelf &setTextLineSpace(lv_coord_t value) { return lv_style_set_text_line_space(raw(), value), _self(); }
		inline TSelf &setTextDecor(lv_text_decor_t value) { return lv_style_set_text_decor(raw(), value), _self(); }
		inline TSelf &setTextAlign(lv_text_align_t value) { return lv_style_set_text_align(raw(), value), _self(); }
		inline TSelf &setRadius(lv_coord_t value) { return lv_style_set_radius(raw(), value), _self(); }
		inline TSelf &setClipCorner(bool value) { return lv_style_set_clip_corner(raw(), value), _self(); }
		inline TSelf &setOpa(lv_opa_t value) { return lv_style_set_opa(raw(), value), _self(); }
		inline TSelf &setColorFilterDsc(const lv_color_filter_dsc_t *value) { return lv_style_set_color_filter_dsc(raw(), value), _self(); }
		inline TSelf &setColorFilterOpa(lv_opa_t value) { return lv_style_set_color_filter_opa(raw(), value), _self(); }
		inline TSelf &setAnimTime(uint32_t value) { return lv_style_set_anim_time(raw(), value), _self(); }
		inline TSelf &setAnimSpeed(uint32_t value) { return lv_style_set_anim_speed(raw(), value), _self(); }
		inline TSelf &setTransition(const lv_style_transition_dsc_t *value) { return lv_style_set_transition(raw(), value), _self(); }
		inline TSelf &setBlendMode(lv_blend_mode_t value) { return lv_style_set_blend_mode(raw(), value), _self(); }
		inline TSelf &setLayout(uint16_t value) { return lv_style_set_layout(raw(), value), _self(); }
		inline TSelf &setBaseDir(lv_base_dir_t value) { return lv_style_set_base_dir(raw(), value), _self(); }
		inline TSelf &setSize(lv_coord_t value) { return lv_style_set_size(raw(), value), _self(); }
		inline TSelf &setPadAll(lv_coord_t value) { return lv_style_set_pad_all(raw(), value), _self(); }
		inline TSelf &setPadHor(lv_coord_t value) { return lv_style_set_pad_hor(raw(), value), _self(); }
		inline TSelf &setPadVer(lv_coord_t value) { return lv_style_set_pad_ver(raw(), value), _self(); }
		inline TSelf &setPadGap(lv_coord_t value) { return lv_style_set_pad_gap(raw(), value), _self(); }
		inline TSelf &setFlexFlow(lv_flex_flow_t value) { return lv_style_set_flex_flow(raw(), value), _self(); }
		inline TSelf &setFlexMainPlace(lv_flex_align_t value) { return lv_style_set_flex_main_place(raw(), value), _self(); }
		inline TSelf &setFlexCrossPlace(lv_flex_align_t value) { return lv_style_set_flex_cross_place(raw(), value), _self(); }
		inline TSelf &setFlexTrackPlace(lv_flex_align_t value) { return lv_style_set_flex_track_place(raw(), value), _self(); }
		inline TSelf &setFlexGrow(uint8_t value) { return lv_style_set_flex_grow(raw(), value), _self(); }
		inline TSelf &setGridRowDscArray(const lv_coord_t value[]) { return lv_style_set_grid_row_dsc_array(raw(), value), _self(); }
		inline TSelf &setGridColumnDscArray(const lv_coord_t value[]) { return lv_style_set_grid_column_dsc_array(raw(), value), _self(); }
		inline TSelf &setGridRowAlign(lv_grid_align_t value) { return lv_style_set_grid_row_align(raw(), value), _self(); }
		inline TSelf &setGridColumnAlign(lv_grid_align_t value) { return lv_style_set_grid_column_align(raw(), value), _self(); }
		inline TSelf &setGridCellColumnPos(lv_coord_t value) { return lv_style_set_grid_cell_column_pos(raw(), value), _self(); }
		inline TSelf &setGridCellColumnSpan(lv_coord_t value) { return lv_style_set_grid_cell_column_span(raw(), value), _self(); }
		inline TSelf &setGridCellRowPos(lv_coord_t value) { return lv_style_set_grid_cell_row_pos(raw(), value), _self(); }
		inline TSelf &setGridCellRowSpan(lv_coord_t value) { return lv_style_set_grid_cell_row_span(raw(), value), _self(); }
		inline TSelf &setGridCellXAlign(lv_coord_t value) { return lv_style_set_grid_cell_x_align(raw(), value), _self(); }
		inline TSelf &setGridCellYAlign(lv_coord_t value) { return lv_style_set_grid_cell_y_align(raw(), value), _self(); }
		//+gen
	};

} /* namespace lvglpp */

#endif /* LVSTYLE_H_ */
